package com.king.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Sentinel Demo
 * 流控效果:
 * 快速失败: DefaultController
 * 预热: WarmUpController, 默认冷加载因子是3
 * 排队等待: RateLimiterController
 * <p>
 * 降级策略:
 * 平均响应时间(DEGRADE_GRADE_RT):
 * 异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):
 * 异常数(DEGRADE_GRADE_EXCEPTION_COUNT):
 * <p>
 * 热点规则(只支持QPS):
 * SentinelResource(value = "value", blockHandler = "blockHandler")
 * blockHandler自定义兜底方法, 定义了热点规则之后必须定义 blockHandler, 否则会出现Error Page
 * BlockException: Sentinel抛出的异常
 * <p>
 * 系统规则:
 * Load 自适应(仅对Linux/Unix-like机器生效):
 * CPU usage:
 * 平均RT:
 * 并发编程数:
 * 入口QPS:
 *
 * @author king
 * @date 2020/10/18 17:06
 */
@RestController
public class FlowLimitController {

    /**
     * 测试流控效果
     *
     * @return
     */
    @GetMapping("/testA")
    public String testA() {
//        try {
//            Thread.sleep(800);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return "testA";
    }

    /**
     * 测试流控效果
     *
     * @return
     */
    @GetMapping("/testB")
    public String testB() {
        return "testB";
    }

    /**
     * 测试降级策略
     *
     * @return
     */
    @GetMapping("/testC")
    public String testC() {
        // RT
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        // 异常比例 / 异常数
        int i = 10 / 0;
        return "testC";
    }

    /**
     * 热点规则
     *
     * @param p1
     * @param p2
     * @return
     */
    @GetMapping("/hotKey")
    @SentinelResource(value = "hotKey", blockHandler = "deal_hotKey")
    public String hotKey(@RequestParam(value = "p1", required = false) String p1,
                         @RequestParam(value = "p2", required = false) String p2) {
        return "hotKey";
    }

    /**
     * SentinelResource 兜底方法
     *
     * @param p1
     * @param p2
     * @param e
     * @return
     */
    public String deal_hotKey(String p1, String p2, BlockException e) {
        // 自定义错误提示
        return "hotKey兜底方法";
    }
}
